home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / c / SUPRALib.lha / SUPRALib / Developer / Source / RecDirNext.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-30  |  7.4 KB  |  243 lines

  1. /****** RecDirNext ***************************************************
  2. *
  3. *   NAME
  4. *       RecDirNext -- Gets information about the next file (V10)
  5. *       (dos V36)
  6. *
  7. *   SYNOPSIS
  8. *       error = RecDirNext(RecDirInfo, RecDirFIB);
  9. *
  10. *       UBYTE = RecDirNext(struct RecDirInfo *, struct RecDirFIB *);
  11. *
  12. *   FUNCTION
  13. *       Retrieves information about the next file in a scanning process.
  14. *       Calling this function  will not provide a list of sorted files
  15. *       niether by ASCII order nor by directory levels. That means
  16. *       it will scan files as they have been stored on a disk drive.
  17. *
  18. *       The main advantage of using this function from using ExNext()
  19. *       is that you don't have to program a recursive scanning routine
  20. *       by yourself. You need only to provide lowest directory path,
  21. *       how deep into subdirectories you want to scan, and which
  22. *       information about files you need to be provided with.
  23. *       RecDirNext() will only return files but no directories.
  24. *       You are also able to select a matching pattern so that only
  25. *       files which match it will be returned.
  26. *
  27. *       Please see RecDirInit() for more info.
  28. *
  29. *   INPUTS
  30. *       RecDirInfo - pointer to RecDirInfo structure. You MUST call
  31. *       RecDirInit(), providing it with this structure, before calling
  32. *       any RecDirNext() function.
  33. *
  34. *       RecDirFIB - pointer to RecDirFIB structure which should be
  35. *       previousely allocated. You only set those fields in the
  36. *       structure that you want to have information about. Any field
  37. *       should point to a variable into which information will be stored.
  38. *       Check "struct RecDirFIB" to see what each field mean.
  39. *       All field in RecDirFIB structure that are set to NULL will be
  40. *       ignored.
  41. *
  42. *   RESULT
  43. *       error - zero if no error. Otherwise one of the following:
  44. *           DN_ERR_END - scanning is completed. You should not call
  45. *                        any RecDirNext() again.
  46. *           DN_ERR_EXAMINE - Failure while examining a file.
  47. *           DN_ERR_MEM - not enough memory available to complete
  48. *                        the operation.
  49. *           IF any error will be resulted, RecDirFree will be called
  50. *           internally.
  51. *
  52. *
  53. *   EXAMPLE
  54. *       This example will scan through the entire HD0: disk device, and
  55. *       will print for each file: its dir path, its name, its size.
  56. *
  57. *
  58. *   #include <stdio.h>
  59. *   #include <stdlib.h>
  60. *   #include <clib/exec_protos.h>
  61. *   #include <clib/dos_protos.h>
  62. *   #include <libraries/supra.h>
  63. *
  64. *   struct RecDirFIB rdf;
  65. *   struct RecDirInfo rdi;
  66. *   char name[30];
  67. *   char path[100];
  68. *   LONG size;
  69. *   LONG err;
  70. *
  71. *   struct DosBase *DosBase;
  72. *
  73. *   void main()
  74. *   {
  75. *        if (DosBase = (struct DosBase *)OpenLibrary("dos.library",0)) {
  76. *
  77. *           rdi.rdi_Path = "RAM:";  \* from path "RAM:" *\
  78. *           rdi.rdi_Num = -1;       \* Unlimited subdirs deep *\
  79. *           rdi.rdi_Pattern = NULL; \* Don't match files for pattern *\
  80. *
  81. *           if (RecDirInit(&rdi) == 0) {
  82. *               rdf.Path = path;  \* We want to get files' path, name and size *\
  83. *               rdf.Name = name;
  84. *               rdf.Size = &size;
  85. *               while ((err = RecDirNext(&rdi, &rdf)) == 0) {
  86. *                   printf("%s (%s) %ld\n", path, name, size);
  87. *               }
  88. *
  89. *               \* Now check if DN_ERR_END or some other unexpected error *\
  90. *               switch (err) {
  91. *                   case DN_ERR_END:
  92. *                       printf("Scanning completed\n");
  93. *                       break;
  94. *                   case DN_ERR_EXAMINE:
  95. *                       printf("Error: trouble examining a file\n");
  96. *                       break;
  97. *                   case DN_ERR_MEM:
  98. *                       printf("Error: not enough memory\n");
  99. *               }
  100. *           }
  101. *
  102. *           CloseLibrary((struct Library *)DosBase);
  103. *       } else printf("Cannot open dos.library\n");
  104. *   }
  105. *
  106. *
  107. *   NOTES
  108. *       If you want to end scanning earlier you have to call RecDirFree()!
  109. *
  110. *   BUGS
  111. *       none found
  112. *
  113. *   SEE ALSO
  114. *       RecDirInit(), RecDirTags(), RecDirFree(), libraries/supra.h
  115. *
  116. *
  117. *   CHANGES
  118. *        Expand function and if's for vbcc
  119. *
  120. **************************************************************************/
  121.  
  122. #include <proto/exec.h>
  123. #include <proto/dos.h>
  124. #include <exec/memory.h>
  125. #include <dos/dos.h>
  126. #include <string.h>
  127. #include <libraries/supra.h>
  128.  
  129. UBYTE RecDirNext(struct RecDirInfo *rdi, struct RecDirFIB *rdf)
  130. {
  131.     struct LockNode *ln,*newln;
  132.     struct FileInfoBlock *fib;
  133.     BPTR lock=0;
  134.     int len;
  135.     char *path;
  136.     int repeat;
  137.  
  138.     do {
  139.         repeat = FALSE;
  140.         ln = rdi->rdi_Node;
  141.         fib = ln->ln_FIB;
  142.  
  143.         if (ExNext(ln->ln_Lock, fib))
  144.         {
  145.             len = strlen(ln->ln_Path)+strlen(fib->fib_FileName);
  146.             if (fib->fib_DirEntryType < 0)   /* This is a file */
  147.             {
  148.                 if (rdi->rdi_Pattern==NULL || MatchPattern(rdi->rdi_Pattern, fib->fib_FileName))
  149.                 {
  150.                     /* Start filling the RecDirFIB structure */
  151.                     if (rdf->Name) strcpy(rdf->Name, fib->fib_FileName);
  152.                     if (rdf->Path) strcpy(rdf->Path, ln->ln_Path);
  153.                     if (rdf->Full)
  154.                     {
  155.                         strcpy(rdf->Full, ln->ln_Path);
  156.                         strcat(rdf->Full, fib->fib_FileName);
  157.                     }
  158.                     if (rdf->Size) *rdf->Size = fib->fib_Size;
  159.                     if (rdf->Flags) *rdf->Flags = fib->fib_Protection;
  160.                     if (rdf->Comment) strcpy(rdf->Comment, fib->fib_Comment);
  161.                     if (rdf->Date) memcpy(rdf->Date, &fib->fib_Date, sizeof(struct DateStamp));
  162.                     if (rdf->Blocks) *rdf->Blocks = fib->fib_NumBlocks;
  163.                     if (rdf->UID) *rdf->UID = fib->fib_OwnerUID;
  164.                     if (rdf->GID) *rdf->GID = fib->fib_OwnerGID;
  165.                     if (rdf->FIB) memcpy(rdf->FIB, fib, sizeof(struct FileInfoBlock));
  166.                     return(0L);
  167.                 } /* Pattern matched */
  168.                 repeat = TRUE; /* Pattern not matched */
  169.             }
  170.             else if (rdi->rdi_Deep < rdi->rdi_Num || rdi->rdi_Num == -1) /* This is a directory */
  171.             {
  172.                 if (path = AllocMem(len+2,0))
  173.                 {
  174.                     strcpy(path, ln->ln_Path);
  175.                     strcat(path, fib->fib_FileName);
  176.                     strcat(path, "/");
  177.  
  178.                     fib = NULL;
  179.  
  180.                     lock = Lock(path, ACCESS_READ);
  181.                     if (lock)
  182.                     {
  183.                         fib = AllocMem(sizeof(struct FileInfoBlock), 0L);
  184.                         if (fib)
  185.                         {
  186.                             if (Examine(lock, fib))
  187.                             {
  188.                                 /* Set up a new LockNode */
  189.                                 newln = AllocMem(sizeof(struct LockNode), 0L);
  190.                                 if (newln)
  191.                                 {
  192.                                     rdi->rdi_Deep++;
  193.                                     rdi->rdi_Node = newln;
  194.                                     ln->ln_Succ = newln;
  195.                                     newln->ln_Pred = ln;
  196.                                     newln->ln_Succ = NULL;
  197.                                     newln->ln_Lock = lock;
  198.                                     newln->ln_FIB= fib;
  199.                                     newln->ln_Path = path;
  200.                                     newln->ln_Len= len+2;
  201.                                     repeat = TRUE;
  202.                                 }
  203.                             }
  204.                         }
  205.                     }
  206.                 }
  207.  
  208.                 if (repeat == FALSE)             /* MEMORY ERROR! */
  209.                 {
  210.                     if (fib) FreeMem(fib, sizeof(struct FileInfoBlock));
  211.                     if (lock) UnLock(lock);
  212.                     if (path) FreeMem(path, len+2);
  213.                     RecDirFree(rdi);
  214.                     return(DN_ERR_MEM);
  215.                 }
  216.             } /*Examined file was file or dir */
  217.         }
  218.         else    /* ExNext failed: probably no more files in current dir */
  219.         {
  220.             if (IoErr() != ERROR_NO_MORE_ENTRIES)        /* Something very wrong */
  221.             {
  222.                 RecDirFree(rdi);
  223.                 return(DN_ERR_EXAMINE);
  224.             }
  225.             else
  226.             {             /* Erase last LockNode */
  227.                 FreeMem(ln->ln_Path, ln->ln_Len);
  228.                 FreeMem(ln->ln_FIB, sizeof(struct FileInfoBlock));
  229.                 UnLock(ln->ln_Lock);
  230.                 newln=ln->ln_Pred;
  231.                 FreeMem(ln, sizeof(struct LockNode));
  232.                 newln->ln_Succ = NULL;
  233.                 rdi->rdi_Node = newln;
  234.                 rdi->rdi_Deep--;
  235.                 if (rdi->rdi_Deep == 0) return(DN_ERR_END); /* Scanning complete */
  236.  
  237.                 repeat = TRUE;
  238.             }
  239.         }
  240.     }
  241.     while (repeat == TRUE);
  242. }
  243.